package com.iocup.keybastion.authorize.decision;


import com.google.common.collect.Sets;
import com.iocup.keybastion.annotion.HasPermission;
import com.iocup.keybastion.authorize.HasAuthorizationProvider;
import com.iocup.keybastion.authorize.element.AuthElement;
import com.iocup.keybastion.context.WebContextHolder;
import com.iocup.keybastion.annotion.Logical;
import com.iocup.keybastion.core.profile.UserProfile;
import com.iocup.keybastion.utils.AuthUtils;
import com.pine.sunflower.core.validate.Validator;
import org.apache.commons.collections4.CollectionUtils;

import java.util.List;
import java.util.Set;
/**
 * @Description: 是否拥有权限
 * @Author: xyjxust
 * @Date: 2022/3/22 13:52
 */
public class HasPermissionDecision implements AuthDecision {
    private HasAuthorizationProvider hasAuthorizationProvider;

    public HasPermissionDecision(HasAuthorizationProvider hasAuthorizationProvider) {
        Validator.build().validate(hasAuthorizationProvider == null, "HasAuthorizationProvider不能为空")
                .throwIfFail();
        this.hasAuthorizationProvider = hasAuthorizationProvider;
    }

    @Override
    public boolean decide(List<AuthElement> list, WebContextHolder webContext) {
        if (CollectionUtils.isEmpty(list)) {
            return true;
        }
        UserProfile userProfile = AuthUtils.getUserInfo();
        if (userProfile == null) {
            return false;
        }
        Set<String> hasPermissions = hasAuthorizationProvider.getPermissions(userProfile.getLoginName(), userProfile.getDevice());
        if (CollectionUtils.isEmpty(hasPermissions)) {
            return false;
        }
        return list.stream().anyMatch(authElement -> {
            String[] permissions = ((String) authElement.getParam(HasPermission.VALUE)).split(",");
            Logical logical = Logical.valueOf(authElement.getParam(HasPermission.LOGICAL));
            return AuthUtils.checkPermissions(logical, Sets.newHashSet(permissions), hasPermissions);
        });
    }

    @Override
    public String getType() {
        return DecisionType.hasPermission.name();
    }


}
